import math
import random
import socket
import threading
import json

import wiringpi

inBufferPinMask = [8, 9, 7, 0, 2, 3, 12, 13, 14, 21, 22, 23, 24, 25]
outBufferPinMask = [15, 16, 4, 5, 6, 10, 11, 26, 27, 28, 29]
analogOutBufferPinMask = [1]
bool_input = [[0 for _ in range(8)] for _ in range(1024)]
bool_output = [[0 for _ in range(8)] for _ in range(1024)]
enri='pi'
def create_response(code, message, data=None):
    response = {
        "code": code,
        "message": message,
        "data": data
    }
    jsonResp = json.dumps(response)
    return jsonResp
def initializeHardware():
    pass
def is_json(data):
    # 判断是否是json串
    try:
        json.loads(data)
    except json.decoder.JSONDecodeError:
        return False
    return True

def readGPIOData():
    global bool_input
    print("读取GPIO")
    for i in range(14):
        bool_input[math.floor(i/8)][i%8] = wiringpi.digitalRead(inBufferPinMask[i])


# 处理客户端请求的线程函数
def countNonZeroElements():
    count =0
    for i in range(1024):
        for j in range(8):
            if bool_input[i][j] != 0:
                  count=count+1

    return count


def parseSparse():
    # 转成稀疏数组
    print("转成稀疏数组")
    nonZeroCount = countNonZeroElements()
    sparse = [[0 for _ in range(3)] for _ in range(nonZeroCount + 1)]
    sparse[0][0] = 1024
    sparse[0][1] = 8
    sparse[0][2] = nonZeroCount

    # 转换二维数组到稀疏数组形式
    k = 1  # 稀疏数组的初始下标
    for i in range(1024):
        for j in range(8):
            if bool_input[i][j] != 0:
                sparse[k][0] = i
                sparse[k][1] = j
                sparse[k][2] = bool_input[i][j]
                k = k + 1
    return sparse


def randowDataForGPIOData():
    for i in range(14):
        rnd = random.randint(0,1)
        bool_input[math.floor(i/8)][i%8] = rnd


def handle_read_action():
    print("树莓派向远端传输数据")
    print("OUTPUT")
    if enri == 'pi':
        readGPIOData()
    else:
        randowDataForGPIOData()
    sparse = parseSparse()
    return create_response(200,"get data success",sparse);

def handle_write_action(data):
    # 解析远端数据并执行给树莓派针脚
    print("解析远端数据并执行给树莓派针脚")
    if 'bool_output' in data:
        boolOutputData = data["bool_output"]
        print("解析输出数组")
        print("稀疏数组转二维数组")
        rows = len(boolOutputData)
        cols = len(boolOutputData[0])
        # 将稀疏数组中的元素复制到二维数组中
        if cols > 1:
            for i in range(1,rows):
                for j in range(cols):
                    bool_output[i][j] = boolOutputData[i][j]
            for i in range(11):
                if enri == 'pi':
                    wiringpi.digitalWrite(outBufferPinMask[i], *bool_output[math.floor(i/8)][i%8])
                elif enri == 'win':
                    print(*bool_output[math.floor(i/8)][i%8])
                else:
                    pass
        else:
            print("数据均为0")
    if 'int_output' in data:
        intOutputData = data["int_output"]
        if enri == 'pi':
            wiringpi.pwmWrite(analogOutBufferPinMask[0],intOutputData)
        else:
            print(intOutputData)
    return create_response(200,"write success",None)


def handle_client(client_socket, client_address):
    try:
        print('客户端已连接:', client_address)
        while True:
            try:
                # 接收客户端数据
                data = client_socket.recv(1024 * 8)
                print('收到客户端消息:', data)
                if data:
                    response = ""
                    if is_json(data):
                        # 处理数据
                        # 解析JSON数据
                        json_data = json.loads(data.decode('utf-8'))
                        print('解析客户端消息:', json_data)
                        if 'run_model' in json_data:
                            run_model = json_data['run_model']
                            if run_model == 'R':
                                response = handle_read_action()
                            elif run_model == 'W':
                                response = handle_write_action(json_data)
                            else:
                                response = "无效请求！"
                        else:
                            # 处理字段不存在的情况
                            print("字段不存在")

                    client_socket.send(response.encode('utf-8'))
                else:
                    # 客户端断开连接
                    print('客户端已断开连接:', client_address)
                    break
            except Exception as e:
                print(e)
                break
    finally:
        # 清理连接
        client_socket.close()


# 创建一个TCP/IP套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定服务器地址和端口
server_address = ('0.0.0.0', 8081)
server_socket.bind(server_address)

# 监听连接
server_socket.listen(5)
print('服务器已启动，等待客户端连接...')

OUTPUT = 1
INPUT = 0
HIGH = 1
LOW = 0
def initPi():
    wiringpi.wiringPiSetup()
    for i in range(14):
        wiringpi.pinMode(inBufferPinMask[i], INPUT)
        # if i != 0 and i != 1:
        #     wiringpi.pinMode(inBufferPinMask[i], INPUT)
    for i in range(11):
        wiringpi.pinMode(outBufferPinMask[i], OUTPUT)
if enri=='pi':
    initPi()
while True:
    # 等待客户端连接
    client_socket, client_address = server_socket.accept()

    # 创建一个新的线程来处理客户端连接
    client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
    client_thread.start()
